package com.assembly.system.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.assembly.entities.Resources;
import com.assembly.entities.RoleResources;
import com.assembly.system.mapper.ResourcesMapper;
import com.assembly.system.service.IResourcesService;
import com.assembly.util.base.Result;
import com.assembly.util.enums.ResultEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 平台资源信息表 服务实现类
 * </p>
 *
 * @author 丽人平台-www.assembly.com
 * @since 2021-03-29
 */
@Service
public class ResourcesServiceImpl extends ServiceImpl<ResourcesMapper, Resources> implements IResourcesService {

    @Override
    public Result queryUserResourcesTree(String userId) {

        // 1. 通过用户id查询所有的权限(目录/菜单/按钮)
        List<Resources> menuList = baseMapper.queryUserResources(userId);
        // 当userId不存在用户信息, menuList 空的, 如果存在用户但没有分配权限就会有一条空记录
        if(CollectionUtils.isEmpty(menuList)
                || menuList.get(0) == null
        ) {
            return Result.build(ResultEnum.MENU_NO);
        }
        // 2. 获取集合中的目录和菜单放到一个集合中,按钮放到一个集合中
        // 存放目录和菜单集合的
        List<Resources> dirMenuList = new ArrayList<>();
        // 存放按钮集合的,只要权限标识code值
        List<String> buttonList = new ArrayList<>();
        for(Resources menu: menuList) {
            if(menu.getType().equals(1) || menu.getType().equals(2)) {
                dirMenuList.add(menu); // 目录和菜单
            }else {
                buttonList.add(menu.getCode()); // 按钮
            }
        }
        // 3. 封装树状菜单
        List<Resources> menuTreeList = this.buildTree(dirMenuList);
        // 4. 响应数据
        Map<String, Object> data = new HashMap<>();
        data.put("menuTreeList", menuTreeList);
        data.put("buttonList", buttonList);
        return Result.ok(data);
    }

    @Override
    public Result queryResourcesTree(String assemblyType) {
        QueryWrapper<Resources> wrapper = new QueryWrapper();
        wrapper.eq("assembly_type",assemblyType);
        List<Resources> resources = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(resources)
                || resources.get(0) == null){
            return Result.build(ResultEnum.MENU_NO);
        }
        return Result.ok(this.buildTree(resources));
    }

    @Override
    public void saveResources(Resources resources) {
        baseMapper.insert(resources);
    }

    @Override
    public void updateResources(Resources resources) {
        resources.setUpdateDate(new Date());
        baseMapper.updateById(resources);
    }

    @Override
    public List<Resources> queryResourcesByUserId(String userId) {
        List<Resources> menuList = baseMapper.queryUserResources(userId);
        if( CollectionUtils.isEmpty(menuList)
                || menuList.get(0) == null ) {
            return null;
        }
        return menuList;
    }



    /**
     * 判断父菜单id是否等于所有菜单中的某一个菜单的parentId，如果等于，则这个菜单 就是子菜单
     * @param menuList 所有菜单（目录、菜单、按钮）
     * @param menu 父菜单对象
     * @return
     */
    private Resources childrenMenu(List<Resources> menuList, Resources menu) {
        // 存放menu菜单对象的所有子菜单
        List<Resources> children = new ArrayList<>();
        // 循环所有菜单，判断是否为 menu 的子菜单
        for(Resources m: menuList) {
            // 判断每个菜单的parentId是否等于menu对象中的id
            if(m.getParentId().equals( menu.getId() )) {
                children.add( childrenMenu(menuList, m) );
            }
        }
        menu.setChildren(children);
        return menu;
    }

    /**
     *  将菜单封装为树状结构
     * @param menuList 所有的菜单（目录、菜单、按钮）
     * @return 返回已经构建好树菜单集合
     */
    private List<Resources> buildTree(List<Resources> menuList) {
        // 1. 获取根菜单
        List<Resources> rootMenuList = new ArrayList<>();
        for(Resources menu: menuList) {
            // parentId=0为根菜单
            if(menu.getParentId().equals("0")) {
                rootMenuList.add(menu);
            }
        }
        // 2. 根菜单下的子菜单
        for(Resources menu: rootMenuList) {
            // 获取一个个根菜单，获取后再去获取对应的子菜单
            childrenMenu(menuList, menu);
        }
        // 所有根菜单对象中都将子菜单收集在了对应的children对象中
        return rootMenuList;
    }
}
